#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "esp_log.h"

#define UART_PORT       UART_NUM_0
#define BUF_SIZE        1024
#define TXD_PIN         GPIO_NUM_1
#define RXD_PIN         GPIO_NUM_3
#define BAUD_RATE       115200

static const char *TAG = "UART_ECHO";
#define PRINT_BUF_SIZE 256
static char buffer[PRINT_BUF_SIZE];

/* 串口初始化 */
void init_uart(void)
{
    uart_config_t uart_cfg = {
        .baud_rate = BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB,
    };
    ESP_ERROR_CHECK(uart_param_config(UART_PORT, &uart_cfg));
    ESP_ERROR_CHECK(uart_set_pin(UART_PORT, TXD_PIN, RXD_PIN,
                                 UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
    ESP_ERROR_CHECK(uart_driver_install(UART_PORT,
                                        BUF_SIZE,
                                        BUF_SIZE,
                                        0, NULL, ESP_INTR_FLAG_IRAM));
}

/* 接收任务：收到什么就回发什么 */
void rx_task(void *arg)
{
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
    while (true) {
        int len = uart_read_bytes(UART_PORT, data, BUF_SIZE, 20 / portTICK_PERIOD_MS);
        if (len > 0) {
            uart_write_bytes(UART_PORT, (const char *)data, len);
            ESP_LOG_BUFFER_HEXDUMP(TAG, data, len, ESP_LOG_INFO);
        }
    }
    free(data);
}

void print(const char *fmt, ...)
{
    va_list args;
    memset(buffer,0,sizeof(buffer));
    va_start(args, fmt);
    int len = vsnprintf(buffer, sizeof(buffer), fmt, args);
    va_end(args);

    if (len > 0) {
        uart_write_bytes(UART_PORT, buffer, strlen(buffer));
    }
}

void print2(char * msg)
{
    uart_write_bytes(UART_PORT, msg, strlen(msg));
}
/* 主函数 */
/*
void app_main(void)
{
    uart_init();
    xTaskCreate(rx_task, "uart_rx_task", 4096, NULL, 10, NULL);

    // 主循环：每 1 s 发一次提示帧 
    while (true) {
        const char *msg = "ESP32 is running...\r\n";
        uart_write_bytes(UART_PORT, msg, strlen(msg));
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
*/